home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / interp / tclStruct1.2.tar.gz / tclStruct1.2.tar / tclStruct1.2 / stLookup.c < prev    next >
C/C++ Source or Header  |  1995-10-17  |  5KB  |  173 lines

  1. /*
  2.  *    tclStruct package
  3.  *  Support 'C' structures in Tcl
  4.  *
  5.  *  Written by Matthew Costello
  6.  *  (c) 1995 AT&T Global Information Solutions, Dayton Ohio USA
  7.  *
  8.  *  See the file "license.terms" for information on usage and
  9.  *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  */
  11. #include "stInternal.h"
  12. STRUCT_SCCSID("@(#)tclStruct:stLookup.c    1.3    95/10/17")
  13.  
  14.  
  15. /*
  16.  * Look up a type name.  Because this routine is called by trace
  17.  * functions, it may not set error messages in the environment.
  18.  * Instead it will return the error message to the caller.
  19.  * Get an hash table value, by its name
  20.  *
  21.  * returns NULL if not found
  22.  */
  23. Struct_TypeDef *
  24. Struct_GetHashedType(cdata,name)
  25.   ClientData cdata;
  26.   char       *name;
  27. {
  28.     Tcl_HashEntry *entryPtr;
  29.     if ((entryPtr=Tcl_FindHashEntry(Struct_TypeHash(cdata),name))!=NULL)
  30.     return (Struct_TypeDef *)Tcl_GetHashValue(entryPtr);
  31.     else
  32.     return NULL;
  33. }
  34.  
  35. /*
  36.  * Struct_LookupType
  37.  *
  38.  *    Look up a type name and returns a pointer to a type.
  39.  *
  40.  * Examples of valid types:
  41.  *    int
  42.  *    my_type_def_t
  43.  *    int*4
  44.  *    ^int
  45.  *    ^int*6
  46.  *
  47.  * Result:
  48.  *    Returns a pointer to the attached type.
  49.  *    NULL returned and interp->result set on error.
  50.  *
  51.  * Side Effects:
  52.  *    'type' has been attached
  53.  */
  54. Struct_TypeDef *
  55. Struct_LookupType(cdata, interp, typename)
  56.   ClientData cdata;
  57.   Tcl_Interp *interp;
  58.   CONST char *typename;
  59. {
  60.     Struct_TypeDef *type;
  61.     Struct_TypeDef *basetype;
  62.     char *s, *p;
  63. #ifdef DEBUG
  64.     if (struct_debug & (DBG_LOOKUP|DBG_PARSETYPE))
  65.     printf("Struct_LookupType( typename = \"%s\" )\n", typename );
  66. #endif
  67.     if (cdata == NULL) {
  68.     Tcl_AppendResult(interp, "NULL package info in Struct_LookupType",NULL);
  69.     return NULL;
  70.     }
  71.  
  72.     /*  The 'pointer' designation has the loosest binding,
  73.      *  therefore we check for it first.
  74.      */
  75.     if (*typename == '^') {
  76.     /*  Look up the base type.  */
  77.     if ((basetype = Struct_LookupType(cdata,interp,typename+1)) == NULL)
  78.         return NULL;
  79.  
  80.     /*  Create the new pointer type.  */
  81.     type = Struct_NewType(cdata,interp,NULL,sizeof(char *),
  82.         STRUCT_FLAG_USE_NULLOK|STRUCT_FLAG_NULL_OK|
  83.         STRUCT_FLAG_USE_STRICT|STRUCT_FLAG_STRICT|
  84.         STRUCT_FLAG_IS_POINTER|STRUCT_FLAG_ALIGN_SIZE,
  85.         Struct_TracePtr );
  86.     if (type == NULL) {
  87.         Struct_ReleaseType(basetype);
  88.         return NULL;
  89.     }
  90.     type->u.a.array_elem = basetype;
  91.     return type;
  92.     }
  93.  
  94.     /*  The array designation is the next lowest...
  95.      */
  96.     if ((s = strrchr( typename, '*' )) != NULL) {
  97.     int nelem;
  98.     *s = '\0';
  99.     basetype = Struct_LookupType(cdata,interp,(char *)typename);
  100.     *s++ = '*';
  101.     if (basetype == NULL)
  102.         return NULL;
  103.     if (basetype->flags & STRUCT_FLAG_VARLEN) {
  104.         Tcl_AppendResult(interp, "cannot construct array from variable length type",NULL);
  105.         Struct_ReleaseType(basetype);
  106.         return NULL;
  107.     }
  108.     if (Tcl_GetInt(interp,s,&nelem) == TCL_ERROR) {
  109.         Struct_ReleaseType(basetype);
  110.         return NULL;
  111.     }
  112.     type = Struct_DefArray(cdata, interp, basetype, nelem );
  113.     Struct_ReleaseType(basetype);
  114. #ifdef DEBUG
  115.     if (struct_debug & (DBG_LOOKUP))
  116.     printf("Struct_LookupType( typename = \"%s\" ) = %s\n",
  117.         typename, Struct_TypeName(type) );
  118. #endif
  119.     return type;
  120.     }
  121.  
  122.     /*  Is this a parameterized type?  */
  123.     if ( ((s = strchr( typename, '(' )) != NULL) &&
  124.          ((p = strchr( s+1, ')' )) != NULL) &&
  125.      (p[1] == '\0') ) {
  126.     int nelem;
  127.     *s = '\0';
  128.     basetype = Struct_LookupType(cdata,interp,(char *)typename);
  129.     *s++ = '(';
  130.     if (basetype == NULL)
  131.         return NULL;
  132.     if (!(basetype->flags & STRUCT_FLAG_VARLEN)) {
  133.         Tcl_AppendResult(interp, "\"",typename,"\" is not a variable length type",NULL);
  134.         Struct_ReleaseType(basetype);
  135.         return NULL;
  136.     }
  137.  
  138.     nelem = strtoul( s, &s, 10 );
  139.     if (s != p) {
  140.         Tcl_AppendResult(interp, "\"",typename,"\" has invalid length",NULL);
  141.         return NULL;
  142.     }
  143.     if (nelem < 0) {
  144.         Tcl_ResetResult(interp);
  145.         sprintf(interp->result,"negative array size of %d is illegal",nelem);
  146.         return NULL;
  147.     }
  148.  
  149.     type = Struct_InstantiateType(cdata, interp, (char *)typename, basetype, nelem );
  150.  
  151. #ifdef DEBUG
  152.     if (struct_debug & (DBG_LOOKUP))
  153.     printf("Struct_LookupType( typename = \"%s\" ) = %s\n",
  154.         typename, Struct_TypeName(type) );
  155. #endif
  156.     return type;
  157.     }
  158.  
  159.     /*  Perhaps we just have a simple type name */
  160.     if ((type = Struct_GetHashedType(cdata,(char *)typename)) != NULL) {
  161.     Struct_AttachType(type);
  162. #ifdef DEBUG
  163.     if (struct_debug & (DBG_LOOKUP))
  164.     printf("Struct_LookupType( typename = \"%s\" ) = %s\n",
  165.         typename, Struct_TypeName(type) );
  166. #endif
  167.     return type;
  168.     }
  169.  
  170.     Tcl_AppendResult(interp, "\"",typename,"\" is not a registered type",NULL);
  171.     return NULL;
  172. }
  173.